﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@algoplus.co.uk website <http://www.algo-plus.co.uk/>
using System;
using System.Collections.Generic;
using System.Linq;
using FinPlusCompCore;
using FinPlusAssembler;
using FinPlusInterfaces;
using s = FinPlusBaseMath.Statistics;

namespace FinPlusCompAlgo
{
    public class AlgPlusRegression : FinPlusComponent
    {
        [State(Test = true)]
        public override bool IsValid { get; set; }
        [State(Test = true)]
        public override string TestString { get { return Adapter.ToString(); } }

        public override IPods Adapter { get { return _adapter; } }

        private enum Params { Reg }
        private IFinPlusComp _feedConn;
        private readonly IPods _adapter;
        private readonly IList<string> _periods;
        private readonly string _name, _value;
        private readonly short _from, _decimalPlaces;

        //construct
        public AlgPlusRegression(IFinPlusComp feed, short from, string name, string value, IList<string> periods, short decimalPlaces)
        {
            _feedConn = feed;
            _from = from;
            _decimalPlaces = decimalPlaces;
            _periods = periods;
            _name = name;
            _value = value;
            _adapter = IOC.New<IPods>(); 
        }

        //common control interface
        public override void CmdExecute(IPod command)
        {
            try
            {
                CmdCapture(command);
            }
            catch (CmdExecuteException e)
            {
                IsValid = Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        public override void Dispose()
        {
            if (_feedConn != null)
                _feedConn.Dispose();
        }

        //private
        private void CalcRegressions(IFinPlusComp feed)
        {
            _feedConn = feed;
            foreach(var period in _periods)
                CalcRegression(period);
        }

        private void CalcRegression(string period)
        {
            var res = _feedConn.Adapter.ToList(_name, _value).First().Where(i => i.Index >= _from);
            var pod = IOC.New<IPod>(Params.Reg.ToString(), "-1");

            var reg1 = s.RegressMaxChange(res.Select(i => (double)i.Object).ToArray<double>(), (int)period.IntParse(), false);
            pod[string.Format("{0}|+|{1}", Params.Reg.ToString(), period)] = Math.Round(reg1, _decimalPlaces); 
            _adapter.Add(pod);

            var reg2 = s.RegressMaxChange(res.Select(i => (double)i.Object).ToArray<double>(), (int)period.IntParse(), true);
            pod[string.Format("{0}|-|{1}", Params.Reg.ToString(), period)] = Math.Round(reg2, _decimalPlaces);
            _adapter.Add(pod);
        }
    }
}
